package site.jlopen.service.imp;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Base64;

import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import site.jlopen.entity.file.FileUploadRes;
import site.jlopen.service.intf.FileUploadService;


@Service("FileUploadService")
public class FileUploadServiceImpl implements FileUploadService {
	private final static Logger logger = LoggerFactory.getLogger(FileUploadServiceImpl.class);

	@Value("${file.local.view}")
	private String fileView;
	@Value("${file.local.dir}")
	private String fileDir;
	@Value("${file.cert.dir}")
	private String certDir;

	@Override
	public FileUploadRes upload(File file, String path, String rename) {
		path = addPath(path);
		boolean create = hasDir(fileDir + path, true);
		if (create == false) {
			return FileUploadRes.error("创建文件夹异常");
		}
		if (null == file) {
			return FileUploadRes.error("目标文件不存在");
		}
		if (file.isFile() == false) {
			return FileUploadRes.error("目标文件非正常文件");
		}
		File destDir = new File(fileDir + path, rename);
		try {
			FileUtils.copyFile(file, destDir);
			return FileUploadRes.success(file.getName(), rename, path, addUrl(path, rename), file.length());
		} catch (IOException e) {
			logger.error("保存文件{}到{}异常：{}", file.getName(), path, e);
			return FileUploadRes.error("保存失败");
		}
	}

	@Override
	public FileUploadRes upload(MultipartFile file, String path, String rename) {
		path = addPath(path);
		boolean create = hasDir(fileDir + path, true);
		if (create == false) {
			return FileUploadRes.error("创建文件夹异常");
		}
		if (null == file) {
			return FileUploadRes.error("目标文件不存在");
		}
		try {
			file.transferTo(new File(fileDir + path + rename));
			return FileUploadRes.success(file.getOriginalFilename(), rename, path, addUrl(path, rename),
					file.getSize());
		} catch (IllegalStateException e) {
			logger.error("保存文件{}到{}异常：{}", file.getOriginalFilename(), path, e);
		} catch (IOException e) {
			logger.error("保存文件{}到{}异常：{}", file.getOriginalFilename(), path, e);
		}
		return FileUploadRes.error("上传失败");
	}

	@Override
	public FileUploadRes uploadCa(MultipartFile file, String path, String rename) {
		path = addPath(path);
		boolean create = hasDir(certDir + path, true);
		if (create == false) {
			return FileUploadRes.error("创建文件夹异常");
		}
		if (null == file) {
			return FileUploadRes.error("目标文件不存在");
		}
		try {
			file.transferTo(new File(certDir + path + rename));
			return FileUploadRes.success(file.getOriginalFilename(), rename, certDir + path, addUrl(path, rename),
					file.getSize());
		} catch (IllegalStateException e) {
			logger.error("保存文件{}到{}异常：{}", file.getOriginalFilename(), path, e);
		} catch (IOException e) {
			logger.error("保存文件{}到{}异常：{}", file.getOriginalFilename(), path, e);
		}
		return FileUploadRes.error("上传失败");
	}

	@Override
	public FileUploadRes upload(String text, String path, String rename) {
		/** path = addPath(path);
		boolean create = hasDir(fileDir + path, true);
		if (create == false) {
			return FileUploadRes.error("创建文件夹异常");
		}
		if (null == text) {
			text = "";
		}*/
		byte[] bytes = text.getBytes(Charset.forName("UTF-8"));
		return upload(bytes, path, rename);
	}

	@Override
	public FileUploadRes upload(URL url, String path, String rename) {
		boolean create = hasDir(fileDir + path, true);
		if (create == false) {
			return FileUploadRes.error("创建文件夹异常");
		}
		if (null == url) {
			return FileUploadRes.error("访问资源为空");
		}
		path = addPath(path);
		HttpURLConnection conn = null;
		InputStream inputStream = null;
		try {
			conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod(HttpMethod.GET.name());
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setUseCaches(false);
			conn.connect();
			inputStream = conn.getInputStream();
			return upload(inputStream, path, rename);
		} catch (Exception e) {
			logger.error("保存文件{}到{}异常：{}", url.toString(), path, e);
			return FileUploadRes.error("保存失败");
		} finally {
			if (null != conn) {
				conn.disconnect();
			}
		}
	}

	@Override
	public FileUploadRes upload(byte[] bytes, String path, String rename) {
		boolean create = hasDir(fileDir + path, true);
		if (create == false) {
			return FileUploadRes.error("创建文件夹异常");
		}
		path = addPath(path);
		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(fileDir + path + rename);
			fos.write(bytes);
			return FileUploadRes.success(rename, rename, path, addUrl(path, rename), 0);
		} catch (IOException e) {
			logger.error("保存文件{}到{}异常：{}", rename, path, e);
			return FileUploadRes.error("保存失败");
		} finally {
			if (null != fos) {
				try {
					fos.close();
				} catch (IOException e2) {
				}
			}
		}
	}

	@Override
	public FileUploadRes upload(InputStream inStream, String path, String rename) {
		boolean create = hasDir(fileDir + path, true);
		if (create == false) {
			return FileUploadRes.error("创建文件夹异常");
		}
		if (null == inStream) {
			return FileUploadRes.error("目标文件流为空");
		}
		path = addPath(path);
		OutputStream outStream = null;
		try {
			outStream = new FileOutputStream(fileDir + path + rename);
			byte[] buffer = new byte[4096];
			int bytesRead;
			while ((bytesRead = inStream.read(buffer)) != -1) {
				outStream.write(buffer, 0, bytesRead);
			}
			return FileUploadRes.success(rename, rename, path, addUrl(path, rename), 0);
		} catch (IOException e) {
			logger.error("保存文件{}到{}异常：{}", rename, path, e);
			return FileUploadRes.error("保存失败");
		} finally {
			if (null != outStream) {
				try {
					outStream.close();
				} catch (IOException e2) {
				}
			}
			if (null != inStream) {
				try {
					inStream.close();
				} catch (IOException e2) {
				}
			}
		}
	}

	@Override
	public byte[] getBase64ToByte(String base64Str) {
		byte[] decodedBytes = Base64.getDecoder().decode(base64Str);
		return decodedBytes;
	}

	private String addPath(String path) {
		if (!path.startsWith("/")) {
			path = "/" + path;
		}
		if (!path.endsWith("/")) {
			path = path + "/";
		}
		return path;
	}

	private String addUrl(String path, String rename) {
		if (path.contains("\\")) {
			path = path.replace("\\", "/");
		}
		return fileView + path + rename;
	}

	private boolean hasDir(String dir, boolean create) {
		try {
			File file = new File(dir);
			if (file.isFile()) {
				return false;
			}
			if (file.exists()) {
				return true;
			}
			if (create == false) {
				return false;
			}
			return file.mkdirs();
		} catch (Exception e) {
			logger.error("创建文件夹{}异常：{}", dir, e);
			return false;
		}
	}
}
